<?php

namespace app\queue\redis\token;

use app\model\TokenInfo;
use support\Db;
use support\Log;
use Webman\RedisQueue\Consumer;

class Token implements Consumer
{
    // 要消费的队列名
    public $queue = 'queue_token_infos';

    public $connection = 'default';

    public function __construct()
    {
        $this->queue = TokenInfo::$update_redis_queue_key;
    }

    protected function handleData()
    {

    }


    // 消费
    public function consume($data)
    {

        $data['updated_at'] = date('Y-m-d H:i:s');
        $TokenInfo = new TokenInfo();
        if (env('APP_ENV') != 'production') return;
        $os_id = $data['os_id'];
        $unique_columns = ['udid'];
        $update_column = ['updated_at', 'token', 'cate_id', 'game_id', 'package_id'];
        $attributes = array_intersect_key($data,array_combine($unique_columns, array_fill(0, count($unique_columns), "")));
        $update = array_intersect_key($data,array_combine($update_column, array_fill(0, count($update_column), "")));

        try {
            /*//大数据下，duplicate key性能差
            $status = Db::table($TokenInfo->getTable())->upsert($data,[],$update_column);*/

            /*//无原子性
            $attributes = array_intersect_key($data,array_combine($unique_columns, array_fill(0, count($unique_columns), "")));
            $status = Db::table($TokenInfo->getTable())->updateOrInsert($attributes,$update);*/

            //先直接更新,后再insert ignore
            //正常数据下只有第一次插入时才用insert ignore ，其他正常情况下无删除和replace into 操作,
            //正常数据下也不会update的时候新数据和旧数据完全一样导致$status=0,因为$update有更新时间(updated_at)
            //缺点：高并发情况下，insert ignore 失败也会消耗id（业务层正常不会出现
            $status = Db::table($TokenInfo->getTable())
                ->where($attributes)
                ->update($update);
            if (!$status) {
                $data['created_at'] = $data['updated_at'];
                $status = Db::table($TokenInfo->getTable())->insertOrIgnore($data);
            }
            Log::channel('token')->info($data['udid'] . '-insert_or_update_token_status-' . $status.':'. json_encode($data));
            unset($TokenInfo);
        } catch (\Throwable $exception) {
            Log::channel('token')->error($exception->getMessage() . '::' . json_encode($data));
        }


    }
}